<?php
namespace Icsoc\DataBundle\Model;

use Icsoc\CoreBundle\Logger\ActionLogger;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * 下面中用到info参数的json格式大概为 ；filter搜素(具体提供搜素字段各个接口不一样)，
 *  pagination分页(rows 每页显示条数,page第几页)，sort排序
 *  {"pagination":{"rows":20,"page":"5"},"filter":{"endresult":"0"},"sort":{"field":"id","order":"desc"}}
 * Class BillModel
 * @package Icsoc\DataBundle\Model
 *
 */
class PhoneModel
{

    /** @var \Symfony\Component\DependencyInjection\Container  */
    private $container;

    /** @var \Doctrine\DBAL\Connection  */
    private $dbal;

    //分机类型
    private $phoneType;

    /**
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->dbal = $this->container->get('doctrine.dbal.default_connection');
        $this->phoneType = $this->container->getParameter('phone_type');
    }


    /**
     * 获取分机列表
     * @param array $param 参数，格式为
     *                     array(
     *                         vcc_code,//企业代码
     *                         info,//提供搜素的字段有
     *                              //phone: 分机号
     *                     )
     * @return array
     */
    public function getList(array $param = array())
    {
        $vcc_code = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $info = empty($param['info']) ? '' : $param['info'];
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vcc_code);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //分页搜索相关信息；
        $addInfo = array();
        if (!empty($info)) {
            $addInfo = json_decode($info, true);
            if (json_last_error()) {
                return array('code' => 403, 'message' => 'info格式非json');
            }
        }
        $where = '';
        if (isset($addInfo['filter'])) {
            $where = isset($addInfo['filter']['phone']) && !empty($addInfo['filter']['phone']) ?
                " AND pho_num LIKE '%".$addInfo['filter']['phone']."%' " : '';
        }

        $count = $this->dbal->fetchColumn(
            'SELECT count(*) '.
            'FROM win_phone '.
            'WHERE vcc_id = :vid '.$where,
            array('vid'=>$vid)
        );
        $page = $this->container->get("icsoc_data.helper")->getPageInfo($count, 'win_phone', $addInfo);
        $list = $this->dbal->fetchAll(
            'SELECT id,pho_num,pho_type,pho_pass '.
            'FROM win_phone '.
            'WHERE vcc_id = :vid '.$where.
            'ORDER BY '.$page['sort'].' '.$page['order'].' LIMIT '.$page['start'].','.$page['limit'],
            array('vid'=>$vid)
        );
        $data = array();
        foreach ($list as $v) {
            $v['type_msg'] = isset($this->phoneType[$v['pho_type']]) ? $this->phoneType[$v['pho_type']] : '未设置';
            $v['sip_number'] = $v['pho_type'] == 5 ? 'ss'.$vid.'ss'.$v['pho_num'] : '';//sip远程分机
            $data[] = $v;
        }
        $ret = array(
            'code' => 200,
            'message' =>'ok',
            'total' => $count,
            'page' => $page['page'],
            'totalPage' => $page['totalPage'],
            'data' => $data,
        );
        return $ret;
    }

    /**
     * 添加分机号
     * @param array $param
     *                  array(
     *                         vcc_code,//企业代码
     *                         pho_type,//分机类型
     *                         pho_num，//分机号 array
     *                         pho_star，//分机号开始
     *                         pho_end，//分机号结束
     *                         passtype，//分机密码类型 1随机密码，2，固定密码
     *                         pho_pass，//分机密码
     *                    )
     * @return array
     */
    public function add(array $param = array())
    {
        $vcc_code = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $pho_type = empty($param['pho_type']) ? 0 : $param['pho_type'];
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vcc_code);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        if (!in_array($pho_type, array_keys($this->phoneType))) {
            return array('code'=>403,'message'=>'电话类型值有误(1,5)');
        }
        $actionLogger = $this->container->get('icsoc_core.helper.logger');
        $logger = $this->container->get("logger");
        switch ($pho_type)
        {
            //sip,pstn
            case 1:
            case 2:
                $phones = empty($param['pho_num']) ? array() : $param['pho_num'];
                if (empty($phones)) {
                    return array('code'=>404,'message'=>'电话号码为空');
                }
//                $phones = json_decode($pho_num);
//                if (json_last_error() || !is_array($phones)) {
//                    return new JsonResponse(array('code'=>405,'message'=>'pho_num格式不正确'));
//                }
                foreach ($phones as $phone_item) {
                    $phone_item = trim($phone_item);
                    if (preg_match("/^\d[\d\-]{0,18}\d$/", $phone_item)) {
                        //判断分机数据库中是否已经存在
                        $if_exit_query = $this->dbal->fetchColumn(
                            'SELECT COUNT(*) '.
                            'FROM win_phone '.
                            'WHERE vcc_id = :vcc_id AND pho_num = :pho_num ',
                            array('vcc_id'=>$vid, 'pho_num'=>$phone_item)
                        );
                        if ($if_exit_query > 0) {
                            continue;
                        }
                        $phone_info = array(
                            'pho_num' => $phone_item,
                            'pho_type' => $pho_type,
                            'vcc_id' => $vid
                        );
                        $logStr = $this->container->get('translator')
                            ->trans('Add phone %str%', array('%str%'=>$phone_item));
                        $actionLogger->actionLog(ActionLogger::ACTION_ADD, $logStr);
                        $this->dbal->insert('win_phone', $phone_info);
                    }
                }
                break;
            case 3://sip分机
            case 5:
                //sip远程分机
                $pho_start = empty($param['pho_start']) ? 0 : $param['pho_start'];
                $pho_end = empty($param['pho_end']) ? 0 : $param['pho_end'];
                $pass_type = empty($param['passtype']) ? 1 : $param['passtype'];
                $pho_pass = empty($param['pho_pass']) ? '' : $param['pho_pass'];
                    if (empty($pho_start) || !preg_match("/\d{4,7}/", $pho_start)) {
                    return array('code'=>406,'message'=>'开始分机号格式有误');
                }
                if (!empty($pho_end)) {
                    if (!preg_match("/\d{4,7}/", $pho_end)) {
                        return array('code'=>407,'message'=>'结束分机号格式有误');
                    }
                } else {
                    $pho_end = $pho_start;
                }
                for ($i = $pho_start; $i <= $pho_end; $i++) {
                    $if_exit_query = $this->dbal->fetchColumn(
                        'SELECT COUNT(*) '.
                        'FROM win_phone '.
                        'WHERE vcc_id = :vcc_id AND pho_num = :pho_num ',
                        array('vcc_id'=>$vid, 'pho_num'=>$i)
                    );
                    if ($if_exit_query > 0) {
                        continue;
                    }
                    $data = array();
                    $data['pho_num'] = str_pad($i, 4, '0', STR_PAD_LEFT);
                    if ($pass_type == 1 || empty($pho_pass)) {
                        $data['pho_pass'] = $this->container->get('icsoc_data.helper')->randString() ;
                    } else {
                        $data['pho_pass'] = $pho_pass;
                    }
                    $data['vcc_id'] = $vid;
                    $data['pho_type'] = $pho_type;
                    $this->dbal->insert('win_phone', $data);
                }
                $str = $pho_start.'----'.$pho_end;
                $logStr = $this->container->get('translator')
                    ->trans('Add phone %str%', array('%str%'=>$str));
                $actionLogger->actionLog(ActionLogger::ACTION_ADD, $logStr);
                break;
        }
        if ($pho_type == 1 || $pho_type == 2) {
            return array('code'=>200, 'message'=>'ok');
        } else {
            // 普通模式
            if ($this->container->getParameter('saas_sip_proxy_mode') === false) {
                /**
                 * 如果是sip类型分机则需要重载
                 */
                $res = $this->reloadPhone($vid, $pho_type);
                if ($res['code'] != 200) {
                    $logger->error('重载分机失败:['.$res['message'].']');
                    if ($res['code'] == 410) {
                        $res['message'] = "请求重载分机地址失败";
                    }
                }
                return $res;
            } else {
                // sip代理模式，不需要重载分机
                return array('code'=>200, 'message'=>'ok');
            }
        }
    }

    /**
     * 删除分机号
     * @param array $param
     *                  array(
     *                         vcc_code,//企业代码
     *                         ids=>array(1,2,3)//需要删除的id;
     *                    )
     * @return array
     */
    public function delete(array $param = array())
    {
        $vcc_code = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $arr = empty($param['ids']) ? array() : $param['ids'];
        $logger = $this->container->get("logger");
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vcc_code);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        if (empty($arr) || !is_array($arr)) {
            return array('code'=>403, 'message'=>'ids格式不正确或为空');
        }

        //转整
        $temp = $msg = array();
        foreach ($arr as $v) {
            $value = (int)$v;
            if ($value == 0) {
                continue;
            }
            //查看是否被坐席占用(ag_type 1,ekt登陆，2，manage, ag_sta 为1的是登陆，)
            $count = $this->dbal->fetchColumn(
                "SELECT count(*) FROM win_agent WHERE pho_id = :pid AND is_del = 0 AND vcc_id = :vcc_id AND ag_sta = 1",
                array('pid' => $value, 'vcc_id'=>$vid)
            );
            if ($count > 0) {
                $msg[] = $value;
                continue;
            }
            $temp[] = $value;
        }
        if (empty($temp)) {
            return array('code'=>405, 'message'=>'请查看分机是否有坐席在使用');
        }
        $temp = array_unique($temp);
        $str = implode(',', $temp);
        //查看是否有sip分机,因开启事务有问题；如果这边删除没有commit 在接口那边还能查询的到；
        //$this->dbal->beginTransaction();
        $sipInfo = $this->dbal->fetchAll(
            "SELECT * FROM win_phone WHERE vcc_id = :vid AND id IN($str) AND pho_type IN(3, 5)",
            array('vid'=>$vid)
        );
        $this->dbal->executeQuery("DELETE FROM win_phone WHERE vcc_id = :vid AND id IN ($str)", array('vid'=>$vid));
        //删除redis passord 缓存；以便创建相同的分机号，密码还是以前的 easycti中用到
        foreach ($sipInfo as $sip) {
            $this->container->get('snc_redis.default')->del(sprintf('phoneinfo:%s:%s', $vid, $sip['pho_num']));
            $this->container->get('snc_redis.sip')->del(sprintf('ss%sss%s', $vid, $sip['pho_num']));
        }
        /**
         * 非sip代理模式下需要执行重载
         */
        if (!empty($sipInfo) && $this->container->getParameter('saas_sip_proxy_mode') === false) {
            $res = $this->reloadPhone($vid, $sipInfo[0]['pho_type']);
            if ($res['code'] != 200) {
                //开始回写
                foreach ($sipInfo as $info) {
                    $this->dbal->insert('win_phone', $info);
                }
                $logger->error('重载分机失败:['.$res['message'].']');
                if ($res['code'] == 410) {
                    $res['message'] = "请求重载分机地址失败";
                }
                return $res;
            }
        }
        $actionLogger = $this->container->get('icsoc_core.helper.logger');
        $logStr = $this->container->get('translator')
            ->trans('Delete phone %str%', array('%str%'=>$str));
        $actionLogger->actionLog(ActionLogger::ACTION_DELETE, $logStr);
        return  array('code'=>500, 'message'=>'总结果', 'data'=>array('success'=>$temp, 'fail'=>$msg));
    }

    /**
     * 获取某企业的400号码
     *
     * @param int $vcc_id
     *
     * @return
     */
    public function getCcPhones($vcc_id)
    {
        $phones = $this->dbal->fetchAll(
            "SELECT phone,phone400 FROM cc_phone400s WHERE vcc_id = :vcc_id",
            array('vcc_id'=>$vcc_id)
        );
        $total = count($phones);
        if ($total >= 2) {
            $res['total'] = $total;
            $all = "";
            foreach ($phones as $v) {
                $all .= $v['phone']."[".$v['phone400']."]<br/>";
            }
            $res['allstr']=$all;
            $fivestr = "";
            foreach (array_slice($phones, 0, 2) as $v) {
                $fivestr .= $v['phone']."[".$v['phone400']."] &nbsp;&nbsp;";
            }
            $res['fivestr'] = $fivestr;
            return $res;
        } else {
            $res['total']=$total;
            $str = '';
            foreach ($phones as $v) {
                $str .= $v['phone']."[".$v['phone400']."]<br/>";
            }
            $res['las'] = $str;
            return $res;
        }
    }

    /**
     * 重载分机
     * @param int $vccId (企业id)
     * @param int $phoneType 分机类型（sip远程分机和sip分机处理方式不同）
     * @return array
     */
    private function reloadPhone($vccId, $phoneType = 5)
    {
        $easycti = $this->container->getParameter('easycti');
        $url = sprintf('%s/phone?vcc_id=%s&phone_type=%s', $easycti, $vccId, $phoneType);
        $result = file_get_contents($url);
        if (!$result) {
            //可能地址配错了
            return array('code'=>410, 'message'=>$url);
        }
        $result = json_decode($result, true);
        if (json_last_error() === JSON_ERROR_NONE) {
            $code = isset($result['code']) ? $result['code'] : '';
            $message = isset($result['message']) ? $result['message'] : '';
            if ($code == 200) {
                return array('code'=>200, 'message'=>'ok');
            } else {
                return array('code'=>408, 'message'=>$message);
            }
        } else {
            return array('code'=>409, 'message'=>"重载分机返回格式错误,写入配置文件失败");
        }
    }
}
